package qc.module.demo.api.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import qc.common.core.exception.QCPromptException;
import qc.common.core.utils.DateUtil;
import qc.module.demo.dto.river.RIVERDto;
import qc.module.demo.dto.rsvr.RSVRDto;
import qc.module.demo.dto.water.WaterGetYnswjDataConditionDto;
import qc.module.demo.service.WaterService;

import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 水文 Controller
 *
 * @author QuCheng Tech
 * @since 2023/9/16
 */
@RestController
@RequestMapping("/water")
public class WaterController {
    @Autowired
    private RestTemplate restTemplate;

    private WaterService waterService;

    @Autowired
    public void setWaterService(WaterService waterService) {
        this.waterService = waterService;
    }

    /**
     * 获取云南水文局数据
     *
     * @param condition
     * @return
     * @throws QCPromptException
     */
    @RequestMapping(value = "/ynswj", method = {RequestMethod.POST})
    public String GetYnswjData(@RequestBody WaterGetYnswjDataConditionDto condition) throws QCPromptException, ParseException {
        // 1.判断查询条件
        if (condition == null)
            throw new QCPromptException("查询条件不能为空");
        if (StringUtils.isBlank(condition.getBegintm()))
            throw new QCPromptException("起始时间不能为空！");
        if (StringUtils.isBlank(condition.getEndtm()))
            throw new QCPromptException("截止时间不能为空！");
        //查询站点类型默认为水库
        //if (StringUtils.isBlank(condition.getType()))
        //    throw new QCPromptException("查询站点类型不能为空！");

        // 2.解析时间
        Date beginTime;
        Date endTime;
        try {
            // 解析起始时间和截止时间
            beginTime = DateUtil.parseDate(condition.getBegintm());
        } catch (Exception e) {
            throw new QCPromptException("开始时间解析出错");
        }

        try {
            // 解析起始时间和截止时间
            endTime = DateUtil.parseDate(condition.getEndtm());
        } catch (Exception e) {
            throw new QCPromptException("结束时间解析出错");
        }
        // 3.查询站点类型是否为水库
        boolean isReservoir = true;
        if (!StringUtils.isBlank(condition.getType())) {
            if (StringUtils.equals(condition.getType(), "2"))
                isReservoir = false;
        }

        // 4.根据站点类型查询水库或者河道数据
        if (isReservoir)
            return GetYnswjReservoirData(beginTime, endTime);
        else
            return GetYnswjRiverData(beginTime, endTime);
    }

    /**
     * 获取水库水情数据，保存到数据库
     *
     * @param beginTime 开始时间
     * @param endTime   结束时间
     * @return
     */
    public String GetYnswjReservoirData(Date beginTime, Date endTime) throws QCPromptException {
        // 遍历每天，逐天获取接口中的数据
        Date date = beginTime;
        while (date.before(endTime)) {

            System.out.println("水库数据-" + DateUtil.getDateString(date) + "，从api获取数据开始");

            // 1.获取url中的时间为当天0点至8点
            String dateString = DateUtil.getString(date, "yyyy-M-d");
            String url = "http://www.ynswj.cn/webapi/api/v1/water?itm=1&no_data_visible=true&time=[" + dateString + "%2000:00:00," + dateString + "%2008:00:00]&sttp=RR&station_type=4,5";
            //String url = "http://www.baidu.com";
            System.out.println(url);

            // 2.获取响应的json字符串数据
            String responseBodyString = GetHttpResponseBody(url, HttpMethod.GET, null);
            System.out.println("水库数据-" + DateUtil.getDateString(date) + "，从api获取数据完成，解析结果json开始");

            // 3.解析json字符串数据
            JSONObject responseJsonObject = JSONObject.parseObject(responseBodyString);
            if (responseJsonObject != null) {
                // 解析水库数据Json
                // 获取data值，数组
                JSONArray jsonArray = responseJsonObject.getJSONArray("data");
                for (Object reservoirObject : jsonArray) {
                    //解析每个水库的数据
                    JSONObject reservoirJsonObject = (JSONObject) reservoirObject;

                    //水库ID
                    String stcd = reservoirJsonObject.getString("id");
                    String name = reservoirJsonObject.getString("name");

                    //水库静态信息
                    String lng = reservoirJsonObject.getString("lng");
                    String lat = reservoirJsonObject.getString("lat");
                    String type = reservoirJsonObject.getString("strong_typef");

                    //水库数据信息
                    String tm = reservoirJsonObject.getString("time");
                    String rz = reservoirJsonObject.getString("val");
                    String w = reservoirJsonObject.getString("capacity");
                    String inq = reservoirJsonObject.getString("in_val");
                    String otq = reservoirJsonObject.getString("out_val");

                    System.out.println(stcd + "-" + name + "-" + tm + "-" + rz + "-" + inq + "-" + otq);

                    // 4.将水库数据保存到数据库中
                    RSVRDto dto = new RSVRDto();
                    dto.setSTCD(stcd);
                    dto.setTM(tm);
                    dto.setW(w);
                    dto.setINQ(inq);
                    dto.setOTQ(otq);
                    dto.setRZ(rz);
                    waterService.addRSVR(dto);
                }
            }

            date = DateUtil.addDays(date, 0x1);
        }

        return null;
    }

    /**
     * 获取指定年份的河道水情数据
     *
     * @param year 指定年份
     * @return
     * @throws QCPromptException
     * @throws ParseException
     */
    @RequestMapping(value = "/getYnswjRiverDataByYear", method = {RequestMethod.GET})
    public String GetYnswjRiverDataByYear(@RequestParam Integer year) {
        List<String> allDateList = getDateListByYear(year);

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        allDateList.stream().forEach(date -> {
            Date startDate = null;
            Date endDate = null;
            try {
                startDate = format.parse(date + " 00:00:00");
                endDate = format.parse(date + " 08:00:00");
            } catch (ParseException e) {
                throw new RuntimeException(e);
            }
            System.out.println("开始时间：" + startDate + "，结束时间：" + endDate);
            try {
                GetYnswjRiverData(startDate, endDate);
            } catch (QCPromptException e) {
                throw new RuntimeException(e);
            }
        });
        return null;
    }

    /**
     * 计算指定年份的所有日期
     *
     * @param year 指定年份
     * @return 指定年份内的所有日期
     */
    private static List<String> getDateListByYear(Integer year) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        List<String> allDateList = new ArrayList<>();
        LocalDate startDate = LocalDate.of(year, 1, 1);
        LocalDate endDate = startDate;
        while (year == endDate.getYear()) {
            allDateList.add(endDate.format(formatter));
            endDate = endDate.plusDays(1L);
        }
        return allDateList;
    }

    /**
     * 获取河道水情数据，保存到数据库
     *
     * @param beginTime 开始时间
     * @param endTime   结束时间
     * @return
     */
    public String GetYnswjRiverData(Date beginTime, Date endTime) throws QCPromptException {
        //遍历每天，逐天获取接口中的数据
        Date date = beginTime;
        while (date.before(endTime)) {

            System.out.println("河道数据-" + DateUtil.getDateString(date) + "，从api获取数据开始");

            // 1.获取url中的时间为当天0点至8点
            String dateString = DateUtil.getString(date, "yyyy-M-d");
            String url = "http://www.ynswj.cn/webapi/api/v1/water?itm=1&no_data_visible=true&time=[" + dateString + "%2000:00:00," + dateString + "%2008:00:00]&sttp=ZQ,ZZ";

            System.out.println(url);

            // 2.获取响应的json字符串数据
            String responseBodyString = GetHttpResponseBody(url, HttpMethod.GET, null);
            System.out.println("河道数据-" + DateUtil.getDateString(date) + "，从api获取数据完成，解析结果json开始");

            // 3.解析json字符串数据
            JSONObject responseJsonObject = JSONObject.parseObject(responseBodyString);
            if (responseJsonObject != null) {
                // 解析河道数据Json
                // 获取data值，数组
                JSONArray jsonArray = responseJsonObject.getJSONArray("data");
                for (Object reservoirObject : jsonArray) {
                    //解析每个河道的数据
                    JSONObject reservoirJsonObject = (JSONObject) reservoirObject;

                    //河道ID
                    String stcd = reservoirJsonObject.getString("id");
                    String name = reservoirJsonObject.getString("name");

                    //河道静态信息
                    String lng = reservoirJsonObject.getString("lng");
                    String lat = reservoirJsonObject.getString("lat");
                    String type = reservoirJsonObject.getString("strong_typef");

                    //河道数据信息
                    String tm = reservoirJsonObject.getString("time");
                    String z = reservoirJsonObject.getString("val");
                    String q = reservoirJsonObject.getString("out_val");

                    System.out.println(name + "-" + tm + "-" + z + "-" + q);

                    if (!StringUtils.isBlank(tm)) {
                        // 4.将河道数据保存到数据库中
                        RIVERDto dto = new RIVERDto();
                        dto.setSTCD(stcd);
                        dto.setTM(tm);
                        dto.setQ(q);
                        dto.setZ(z);
                        waterService.addRIVER(dto);
                    }
                }
            }

            date = DateUtil.addDays(date, 0x1);
        }

        return null;
    }

    /**
     * 获取水情响应数据
     *
     * @param url
     * @param method
     * @param formEntity
     * @return
     */
    public String GetHttpResponseBody(String url, HttpMethod method, HttpEntity<String> formEntity) {
        //获取结果为json时设置header中的ContentType
        //HttpHeaders headers = new HttpHeaders();
        //headers.setContentType(MediaType.APPLICATION_JSON);
        ////
        //if (formEntity == null)
        //    formEntity = new HttpEntity<String>(headers);

        //设置编码
        restTemplate.getMessageConverters().set(0x1, new StringHttpMessageConverter(StandardCharsets.UTF_8));

        URI uri = URI.create(url);
        ResponseEntity<String> response = restTemplate.getForEntity(uri, String.class);
        //ResponseEntity<String> response = restTemplate.exchange(
        //        url,
        //        method,
        //        formEntity,
        //        String.class
        //);

        String responseBody = response.getBody();

        return responseBody;
    }

    public static void setRestTemplateEncode(RestTemplate restTemplate) {
        //if (null == restTemplate || ObjectUtils.isEmpty(restTemplate.getMessageConverters())) {
        //    return;
        //}
        //
        //List<HttpMessageConverter<?>> messageConverters = restTemplate.getMessageConverters();
        //for (int i = 0; i < messageConverters.size(); i++) {
        //    HttpMessageConverter<?> httpMessageConverter = messageConverters.get(i);
        //    if (httpMessageConverter.getClass().equals(StringHttpMessageConverter.class)) {
        //        messageConverters.set(i, new StringHttpMessageConverter(StandardCharsets.UTF_8));
        //    }
        //}
    }
}
